package com.zpark.merchant.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zpark.jushanpay.common.domain.BusinessException;
import com.zpark.jushanpay.common.domain.CommonErrorCode;
import com.zpark.jushanpay.common.util.RandomUuidUtil;
import com.zpark.jushanpay.common.util.StringUtil;
import com.zpark.merchant.api.dto.AppDTO;
import com.zpark.merchant.api.service.IAppService;
import com.zpark.merchant.service.convert.IAppConvert;
import com.zpark.merchant.service.entity.App;
import com.zpark.merchant.service.entity.Merchant;
import com.zpark.merchant.service.mapper.IAppMapper;
import com.zpark.merchant.service.mapper.IMerchantMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 应用业务层实现类
 */
@Service
public class AppServiceImpl implements IAppService {

    @Autowired
    private IMerchantMapper merchantMapper;

    @Autowired
    private IAppMapper appMapper;

    @Override
    @Transactional
    public AppDTO createApp(Long merchantId, AppDTO dto) throws BusinessException {
        // 判断merchantId和dto是否有效
        if (StringUtil.isEmpty(merchantId + "") || dto == null
                || StringUtil.isEmpty(dto.getAppName())) {
            // 不能创建应用
            throw new BusinessException(CommonErrorCode.E_100114);
        }

        // 根据merchantId查询商户数据
        Merchant merchant = merchantMapper.selectById(merchantId);
        // 判断商户id是否存在
        if (merchant == null) {
            throw new BusinessException(CommonErrorCode.E_200002);
        }

        // 判断商户的审核状态
        if (!"2".equals(merchant.getAuditStatus())) {
            throw new BusinessException(CommonErrorCode.E_200001);
        }

        // 根据应用名字查询数据，确保应用名字没有被使用
        if (isExistAppName(dto.getAppName())) {
            // 应用名字已经被使用
            throw new BusinessException(CommonErrorCode.E_200003);
        }

        // 如果应用名字没有被使用，则将merchantId设置到appDto当中
        dto.setMerchantId(merchantId);
        dto.setAppId(RandomUuidUtil.getUUID());

        // 将dto转为entity
        App app = IAppConvert.INSTANCE.dtoToEntity(dto);
        // 调用持久层接口添加数据
        appMapper.insert(app);
        // 将Dto返回
        return IAppConvert.INSTANCE.entityToDto(app);
    }

    /**
     * 根据商户id查询所有应用
     * @param merchantId 商户的ID
     * @return
     * @throws BusinessException
     */
    @Override
    public List<AppDTO> queryByMerchantId(Long merchantId) throws BusinessException {
        // 1、构建查询参数对象
        // 2、调用查询方法查询数据  selectList
        List<App> apps = appMapper.selectList(
                new LambdaQueryWrapper<App>()
                        .eq(App::getMerchantId, merchantId)
        );
        // 判断查询结果是否有数据
        if (apps == null || apps.size() <= 0) {
            throw new BusinessException(CommonErrorCode.E_200207);
        }
        // 3、将entity转为dto返回
        return IAppConvert.INSTANCE.listEntityToListDto(apps);
    }

    /**
     * 根据应用ID查询数据
     * @param appId 应用的appId
     * @return
     * @throws BusinessException
     */
    @Override
    public AppDTO queryByAppId(String appId) throws BusinessException {
        // 1、构建查询参数对象
        // 2、调用方法查询数据  selectOne
        App app = appMapper.selectOne(
                new LambdaQueryWrapper<App>()
                        .eq(App::getAppId, appId)
        );
        // 判断查询结果
        if (app == null) {
            throw new BusinessException(CommonErrorCode.E_200207);
        }
        // 将entity转为dto返回
        return IAppConvert.INSTANCE.entityToDto(app);
    }

    /**
     * 根据应用id和商户id校验门店的合法性
     * @param appId 应用appid
     * @param merchantId 商户id
     * @return
     */
    @Override
    public Boolean queryAppInMerchant(String appId, Long merchantId) {
        // 根据appid和merchantid查询数据（查询app表）
        Long count = appMapper.selectCount(
                new LambdaQueryWrapper<App>()
                        .eq(App::getAppId, appId)
                        .eq(App::getMerchantId, merchantId)
        );
        // 判断是否有查询结果，有则返回true，没有则返回false
        return count > 0;
    }


    /**
     * 根据app名字查询数据
     * @param appName app名字
     * @return 是否存在应用名字
     */
    private Boolean isExistAppName(String appName){
        // 根据应用名字查询应用数据
        Long count = appMapper.selectCount(
                new LambdaQueryWrapper<App>()
                        .eq(App::getAppName, appName)
        );

        return count > 0;
    }
}
